package com.icetec.iceintel.model;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import com.icetec.R;
import com.icetec.iceintel.framework.AppApplication;
import com.icetec.iceintel.service.AlarmAlertBroadcastReciever;

/**
 * Created by amo on 2015/2/16.
 * 闹钟实体，可序列化
 */

public class Alarm implements Serializable {



    //闹钟的类型分为唤醒，睡眠，定时三种


    public enum AlarmType {
        AWAKE,
        SLEEP,
        SCHEDULE;
        @Override
        public String toString() {
            switch (this.ordinal()) {
                case 0:
                    return AppApplication.getShareInstance().getString(R.string.awake_alarm);
                case 1:
                    return  AppApplication.getShareInstance().getString(R.string.sleep_alarm);
                case 2:
                    return  AppApplication.getShareInstance().getString(R.string.timer_shut_down);
            }
            return super.toString();
        }
    }


    //闹钟的重复周期

    public enum Day {
        SUNDAY,
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY;

        @Override
        public String toString() {
            switch (this.ordinal()) {
                case 0:
                    return  AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[0];
                case 1:
                    return AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[1];
                case 2:
                    return AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[2];
                case 3:
                    return AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[3];
                case 4:
                    return AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[4];
                case 5:
                    return AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[5];
                case 6:
                    return AppApplication.getShareInstance().getResources().getStringArray(R.array.repeat_days)[6];
            }
            return super.toString();
        }

    }

    private static final long serialVersionUID = 8699489847426803789L;
    private int id;
    private Boolean alarmActive = true;
    private Calendar alarmTime = Calendar.getInstance();
    private Day[] days = {Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY, Day.SATURDAY, Day.SUNDAY};
    private String alarmTonePath = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM).toString();
    private Boolean vibrate = true;
    private String alarmName = AppApplication.getShareInstance().getResources().getString(R.string.default_alarm);
    private AlarmType alarmType =AlarmType.AWAKE;
    private Boolean isOnce =true;
    private String alarmMAC=AppApplication.getShareInstance().getResources().getString(R.string.choose_device);
    private Integer alarmPort=-1;


    public Alarm() {

    }


    public void setAlarmMAC(String alarmMAC) {
        this.alarmMAC = alarmMAC;
    }


    public void setAlarmPort(Integer alarmPort) {
        this.alarmPort = alarmPort;
    }


    public void setIsOnce(Boolean isOnce) {
        this.isOnce = isOnce;
    }

    public Boolean getIsOnce() {
        return isOnce;
    }

    public Integer getAlarmPort() {
        return alarmPort;
    }


    public String getAlarmMAC() {
        return alarmMAC;
    }

    /**
     * @return the alarmActive
     */
    public Boolean getAlarmActive() {
        return alarmActive;
    }

    /**
     * @param alarmActive the alarmActive to set
     */
    public void setAlarmActive(Boolean alarmActive) {
        this.alarmActive = alarmActive;
    }

    /**
     * @return the alarmTime
     */
    public Calendar getAlarmTime() {
        if (alarmTime.before(Calendar.getInstance()))
            alarmTime.add(Calendar.DAY_OF_MONTH, 1);
        while (!Arrays.asList(getDays()).contains(Day.values()[alarmTime.get(Calendar.DAY_OF_WEEK) - 1])) {
            alarmTime.add(Calendar.DAY_OF_MONTH, 1);
        }
        return alarmTime;
    }

    /**
     * @return the alarmTime
     * 将闹钟的时间使用字符串表示出来，格式是XX:XX:XX    天，小时，分
     */
    public String getAlarmTimeString() {

        String time = "";
        if (alarmTime.get(Calendar.HOUR_OF_DAY) <= 9)
            time += "0";
        time += String.valueOf(alarmTime.get(Calendar.HOUR_OF_DAY));
        time += ":";

        if (alarmTime.get(Calendar.MINUTE) <= 9)
            time += "0";
        time += String.valueOf(alarmTime.get(Calendar.MINUTE));

        return time;
    }

    /**
     * 将闹钟的时间使用字符串去设置
     */
    public void setAlarmTime(Calendar alarmTime) {
        this.alarmTime = alarmTime;
    }

    /**
     * 使用格式xx:xx:xx 时分秒  去设置闹钟响应的时间
     */
    public void setAlarmTime(String alarmTime) {

        String[] timePieces = alarmTime.split(":");

        Calendar newAlarmTime = Calendar.getInstance();
        newAlarmTime.set(Calendar.HOUR_OF_DAY,
                Integer.parseInt(timePieces[0]));
        newAlarmTime.set(Calendar.MINUTE, Integer.parseInt(timePieces[1]));
        newAlarmTime.set(Calendar.SECOND, 0);
        setAlarmTime(newAlarmTime);
    }


    public Day[] getDays() {
        return days;
    }


    public void setDays(Day[] days) {
        this.days = days;
    }

    public void addDay(Day day) {
        boolean contains = false;

        //找寻是否已经存在的
        for (Day d : getDays())
            if (d.equals(day))
                contains = true;

        //如果要添加的那个时间，不存在，则添加进去
        if (!contains) {
            List<Day> result = new LinkedList<Day>();
            for (Day d : getDays())
                result.add(d);
            result.add(day);
            setDays(result.toArray(new Day[result.size()]));
        }
    }

    public void removeDay(Day day) {

        List<Day> result = new LinkedList<Day>();
        for (Day d : getDays())
            if (!d.equals(day))
                result.add(d);
        setDays(result.toArray(new Day[result.size()]));
    }


    public String getAlarmTonePath() {
        return alarmTonePath;
    }


    public void setAlarmTonePath(String alarmTonePath) {
        this.alarmTonePath = alarmTonePath;
    }


    public Boolean getVibrate() {
        return vibrate;
    }


    public void setVibrate(Boolean vibrate) {
        this.vibrate = vibrate;
    }


    public String getAlarmName() {
        return alarmName;
    }


    public void setAlarmName(String alarmName) {
        this.alarmName = alarmName;
    }



    public AlarmType getAlarmType(){

        return alarmType;

    }

    public void setAlarmType(AlarmType alarmType) {
        this.alarmType = alarmType;
    }



    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRepeatDaysString() {
        StringBuilder daysStringBuilder = new StringBuilder();

        if(getDays().length==0){
            return AppApplication.getShareInstance().getResources().getString(R.string.single_use);
        }

        if (getDays().length == Day.values().length) {
            daysStringBuilder.append(AppApplication.getShareInstance().getResources().getString(R.string.everyday));
        } else {
            Arrays.sort(getDays(), new Comparator<Day>() {
                @Override
                public int compare(Day lhs, Day rhs) {

                    return lhs.ordinal() - rhs.ordinal();
                }
            });
            for (Day d : getDays()) {
                switch (d) {
                    case TUESDAY:
                    case THURSDAY:
//					daysStringBuilder.append(d.toString().substring(0, 4));
//					break;
                    default:
                        daysStringBuilder.append(d.toString().substring(0, 2));
                        break;
                }
                daysStringBuilder.append(',');
            }
            daysStringBuilder.setLength(daysStringBuilder.length() - 1);
        }

        return daysStringBuilder.toString();
    }


    //此方法用于到达时间点后，发送激活闹钟响应界面的广播
    //使用AlarmManager，到达指定时间点后，自动发送广播

    public void schedule(Context context) {
        setAlarmActive(true);

        Intent myIntent = new Intent(context, AlarmAlertBroadcastReciever.class);
        myIntent.putExtra("alarm", this);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent,PendingIntent.FLAG_CANCEL_CURRENT);
        AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, getAlarmTime().getTimeInMillis(), pendingIntent);
    }

    public String getTimeUntilNextAlarmMessage() {
        long timeDifference = getAlarmTime().getTimeInMillis() - System.currentTimeMillis();
        long days = timeDifference / (1000 * 60 * 60 * 24);
        long hours = timeDifference / (1000 * 60 * 60) - (days * 24);
        long minutes = timeDifference / (1000 * 60) - (days * 24 * 60) - (hours * 60);
        long seconds = timeDifference / (1000) - (days * 24 * 60 * 60) - (hours * 60 * 60) - (minutes * 60);
        String alert = AppApplication.getShareInstance().getString(R.string.alarm_alert);

        if (days > 0) {
            alert += String.format(
                    "%d 天, %d 小时, %d 分钟, %d 秒", days,
                    hours, minutes, seconds);
        } else {
            if (hours > 0) {
                alert += String.format("%d 小时, %d 分钟, %d 秒",
                        hours, minutes, seconds);
            } else {
                if (minutes > 0) {
                    alert += String.format("%d 分钟, %d 秒", minutes,
                            seconds);
                } else {
                    alert += String.format("%d 秒", seconds);
                }
            }
        }
        return alert;
    }

}
